#include "./HttpContext.h"
#include "../../tcp/code/utility/Buffer.h"

bool HttpContext::parseRequest(Buffer *buffer, Timestamp receiveTime)
{
    bool isOk = false;

    bool hasMore = true;
    while (hasMore)
    {
        // 状态转换控制
        if (this->requestParseState_ == RequestParseState::ExpectRequestLine) // 1.请求行
        {
            const char *crlfPos = buffer->findCrlfPos(); // 可读区找crlf
            if (crlfPos)
            {
                isOk = this->praseRequestLine(buffer->readableBegin(), crlfPos); // 可读区解析请求行
                if (isOk)
                {
                    this->request_.setReceiveTime(receiveTime);

                    buffer->moveReadableIndexTo(crlfPos + 2); // 移动索引继续往后解析

                    this->requestParseState_ = RequestParseState::ExpectHeaders;
                }
                else
                {
                    hasMore = false;
                }
            }
            else
            {
                hasMore = false;
            }
        }
        else if (requestParseState_ == RequestParseState::ExpectHeaders) // 2.请求头
        {
            const char *crlfPos = buffer->findCrlfPos();
            if (crlfPos)
            {
                const char *colonPos = std::find(const_cast<const char *>(buffer->readableBegin()), crlfPos, ':');
                if (colonPos != crlfPos)
                {
                    this->request_.setHeader(buffer->readableBegin(), colonPos, crlfPos);
                }
                else // 没有":"，是headers和body的\r\n
                {
                    this->requestParseState_ = RequestParseState::ExpectBody;
                }
                buffer->moveReadableIndexTo(crlfPos + 2); // 无论如何都要移动
            }
            else
            {
                hasMore = false;
            }
        }
        else if (requestParseState_ == RequestParseState::ExpectBody) // 3.请求体，当前值未处理只支持GET
        {
            this->requestParseState_ = RequestParseState::GotAll;
            hasMore = false;
        }
    }

    return isOk;
}

bool HttpContext::praseRequestLine(const char *begin, const char *end)
{
    bool isOk = false;

    const char *cur = begin;
    const char *spacePos = std::find(cur, end, ' ');
    if (spacePos != end && this->request_.setMethod(cur, spacePos)) // 1.第一个空格，前是方法
    {
        cur = spacePos + 1; // 跳过空格

        spacePos = std::find(cur, end, ' ');
        if (spacePos != end) // 2.第二个空格，前是URL
        {
            const char *questionPos = std::find(cur, spacePos, '?');
            if (questionPos != spacePos) // 存在请求参数
            {
                this->request_.setPath(cur, questionPos);
                this->request_.setQuery(questionPos, spacePos);
            }
            else
            {
                request_.setPath(cur, spacePos);
            }
            cur = spacePos + 1;

            // 3.版本
            isOk = (end - cur == 8 && std::equal(cur, end - 1, "HTTP/1."));
            if (isOk)
            {
                if (*(end - 1) == '1')
                {
                    this->request_.setVersion(HttpRequest::Version::Http11);
                }
                else if (*(end - 1) == '0')
                {
                    this->request_.setVersion(HttpRequest::Version::Http10);
                }
                else
                {
                    isOk = false;
                }
            }
        }
    }

    return isOk;
}